#!/usr/bin/python
# -*- coding: utf-8 -*-

# This program only handles the following letters:
#    consonants   (က .. အ, ႏ , ႐); there are more, but we ignore them for now
#    ya-yit            (ၾ---)
#    leg-fwd         (--ွ)
#    circle-below   (--ြ)
#    yay_cha         (--ာ/--ါ), because we can't make any interesting examples without it
# This still allows for some interesting cases:
#  1) Many-to-one: ျ---, ၾ---, ၿ---, ႀ---, ႁ---, ႂ---, ႃ---, ႄ---  ==> ya-yit
#  2) One-to-many: --ႊ  ==> leg-fwd AND circle-below
#  3) Letter-to-category: A "consonant" can be one of many letters.
#  4) Reordering: YA+CONS becomes CONS+YA
#
# NOTE: We only handle a single syllable here. Just put this function inside a loop, if you have an array of syllables.
# NOTE: This function assumes it gets Burmese text (e.g., not English, not Unicode, not ZG09, etc.)

#Our Indexing Constants (We purposefully put them out-of-order to show how it works.)
IND_CONSONANT  = 0
IND_LEG_FWD       = 1
IND_CIRC_BELOW  = 2
IND_YA_YIT          = 3
IND_YAY_CHA       = 4
NUM_INDEXES = 5

#Our grand index, used for saying "what unicode letter(s) does this Zawgyi letter represent"
#   All expected letters MUST be in this index
grand_index = dict((unichr(n), [IND_CONSONANT]) for n in range(0x1000, 0x1021+1))  #Consonants.
grand_index.update({
    u'\u108F':[IND_CONSONANT], u'\u1090':[IND_CONSONANT],   #"Cut off" cases for "na" and "ya"
    u'\u103D':[IND_LEG_FWD], u'\u1087':[IND_LEG_FWD],   #Leg-fwd, "pure" cases
    u'\u102B':[IND_YAY_CHA], u'\u102C':[IND_YAY_CHA],   #Yay-cha, "pure" cases
    u'\u103B':[IND_YA_YIT], u'\u107E':[IND_YA_YIT], u'\u107F':[IND_YA_YIT], u'\u1080':[IND_YA_YIT],     #Ya-yit, "pure" cases
    u'\u1081':[IND_YA_YIT], u'\u1082':[IND_YA_YIT], u'\u1083':[IND_YA_YIT], u'\u1084':[IND_YA_YIT],     #Ya-yit, "pure" cases, ctd.
    u'\u103C':[IND_CIRC_BELOW],   #Circle-below, "pure" case
    u'\u108A':[IND_LEG_FWD, IND_CIRC_BELOW],    #Leg-fwd + circle-below
    u'\u1088':[IND_LEG_FWD], u'\u1089':[IND_LEG_FWD],   #Leg-fwd, mixed with other letters that we haven't defined yet
    u'\u105A':[IND_YAY_CHA],   #Yay-cha, "pure" mixed with other letters that we haven't defined yet
})

#Test Strings: uncomment to test (or just use unix, which accepts Unicode command line args)
#   Note: the last two are made-up words
tests = [u'လႊ', u'ညႇ', u'ႁမြာ', u'ျႏႇာ', u'ႁအႊာ']
input = tests[0]

#Step 1: "Tag" all letters in the Zawgyi word:
tagged_components = [u'']*NUM_INDEXES
for letter in input:
    #Each letter may represent several "parts". 
    #  For each letter, tag all "part" IDs with the string that represents that letter
    parts = grand_index[letter]
    for partID in parts:
        tagged_components[partID] = letter

#Intermission: How does Unicode expect these letters to be ordered?
#  By the way, make sure you define your constants in the way that best helps YOU.
#  For example, you definitely want an "IND_KINZI" constant, instead of "breaking up" kinzi into its parts.
#  You will probably also want an "IND_STACKED" constant, this is much better than breaking up all pat-sint letters.
unicode_order = [IND_CONSONANT, IND_YA_YIT, IND_CIRC_BELOW, IND_LEG_FWD, IND_YAY_CHA]

#Intermission: What consonants are represented differently by Zawgyi, and how do we convert them?
#  Note: Convert to a hash, if you wish
def base_letter(cons):
    if cons==u'\u108F':
        return u'\u1014'
    elif cons==u'\u1090':
        return u'\u101B'
    return None

#Step 2: Output a proper unicode sequence
output = u''
for item in unicode_order:
    #Do we have anything representing this index? 
    expected = tagged_components[item]
    if expected:
        #Process this letter
        if item==IND_CONSONANT:
            #If it's a consonant, just copy what we found, unless it's a cut version
            expected = base_letter(expected) if base_letter(expected) else expected
        elif item==IND_LEG_FWD:
            #Only one representation in Unicode
            expected = u'\u103E'
        elif item==IND_CIRC_BELOW:
            #Only one representation in Unicode
            expected = u'\u103D'
        elif item==IND_YA_YIT:
            #Only one representation in Unicode
            expected = u'\u103C'
        elif item==IND_YAY_CHA:
            #Two possible representations; the "killed tall" letter is the only problem
            expected = u'\u102B' if expected==u'\u105A' else expected
    
        #Now, append it
        output += expected

#Step 3: For the sake of my poor Microsoft command line, output each letter as U+.... values
win32_output = reduce(lambda x,y:x + 'U+'+hex(ord(y)).upper()[2:]+' , ', ' '+output)
print 'Done: ' + win32_output

#Results, compared to Ko Soe Min's converter:
#           \u101C\u103D\u103E
#Done:  U+101C , U+103D , U+103E ,

#           \u100A\u103E
#Done:  U+100A , U+103E ,

#           \u1019\u103C\u103D\u102C
#Done:  U+1019 , U+103C , U+103D , U+102C ,

#           \u1014\u103C\u103E\u102C
#Done:  U+1014 , U+103C , U+103E , U+102C ,

#          \u1021\u103C\u103D\u103E\u102C
#Done:  U+1021 , U+103C , U+103D , U+103E , U+102C ,














